import base64
import json
import urllib

# TODO: (clientId, clientSecret, tokenUrl)请使用实际值替换
# App secret, 在AppGallery Connect创建应用之后，系统自动分配的公钥
clientSecret = "2pi9wffoj9dn633vdb2p85u2oeehmp6o"
# client id指的是您的APP ID
# App ID, 在AppGallery Connect创建应用之后，系统自动分配的唯一标识符
clientId = "1003400"
# 用于获取authorization token的url，具体请参见基于OAuth 2.0开放鉴权
TokenUrl = "https://oauth-login.cloud.huawei.com/oauth2/v3/token"
# accessToken信息
accessToken = None


def getAppAT():
    """获取应用级AccessToken."""
    global accessToken
    if accessToken is not None and accessToken != "":
        return accessToken
    headers = {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
    bodyDict = {"grant_type": "client_credentials", "client_secret": clientSecret, "client_id": clientId}
    data = urllib.parse.urlencode(bodyDict).encode("utf-8")
    response = httpPost(TokenUrl, data, headers)
    if response is not None and response != "":
        jsonObject = json.loads(response)
        accessToken = jsonObject['access_token']
        # TODO: 将accessToken打印到控制台,您可以移除本句
        print(accessToken)
    return accessToken


def httpPost(url, params, headers):
    """Http post的工具方法."""
    global accessToken
    response, statusCode = doPost(url, params, headers)
    # 当状态码为401，表示AT已过期
    if statusCode == 401:
        # 刷新AT
        accessToken = None
        appAt = getAppAT()
        headers = buildAuthorization(appAt)
        # 再次请求
        response, statusCode = doPost(url, params, headers)
    elif statusCode != 200:
        print("request error: " + response)
        response = None
    return response


def doPost(url, params, headers):
    """执行post请求"""
    try:
        errorPro = BetterHTTPErrorProcessor()
        opener = urllib.request.build_opener(errorPro)
        req = urllib.request.Request(url=url, data=params, headers=headers, unverifiable=False, method="POST")
        response = opener.open(req, timeout=50)
        statusCode = response.getcode()
        return str(response.read(), encoding="utf8"), statusCode
    except urllib.error.URLError as e:
        print(e)


def buildAuthorization(appAt):
    """在请求头中构建Authorization"""
    oriString = "APPAT:%s" % appAt
    authorization = "Basic %s" % str(base64.b64encode(oriString.encode('utf-8')), 'utf-8')
    headers = {"Authorization": authorization, "Content-Type": "application/json; charset=UTF-8"}
    return headers


class BetterHTTPErrorProcessor(urllib.request.HTTPErrorProcessor):
    """重写HTTPErrorProcessor."""
    handler_order = 1000

    def http_response(self, request, response):
        code, msg, hdrs = response.code, response.msg, response.info()
        if not (200 <= code < 500):
            response = self.parent.error(
                'http', request, response, code, msg, hdrs)
        return response
    https_response = http_response

if __name__ == '__main__':
    print(getAppAT())
    print(buildAuthorization(getAppAT()))